package com.ncr.travel.appmgr.client.presenter;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.RunAsyncCallback;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimpleCheckBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
import com.ncr.nep.dashboardcore.rest.client.JSONCallback;
import com.ncr.travel.appmgr.client.ConfigurationItem;
import com.ncr.travel.appmgr.client.Constants;
import com.ncr.travel.appmgr.client.command.PostScreenConfigurationCommand;
import com.ncr.travel.appmgr.client.event.ConfigChangeEvent;
import com.ncr.travel.appmgr.client.event.ConfirmConfigChangeEvent;
import com.ncr.travel.appmgr.client.event.ConfirmConfigChangeEventHandler;
import com.ncr.travel.appmgr.client.model.ScreenConfigurationFactory;
import com.ncr.travel.appmgr.client.mvp.BasePresenter;
import com.ncr.travel.appmgr.client.mvp.EventBus;
import com.ncr.travel.appmgr.client.service.AppManagerWebService;
import com.ncr.travel.appmgr.client.view.RuleView;
import com.ncr.travel.appmgr.model.shared.ColumnSpecification;
import com.ncr.travel.appmgr.model.shared.RowSpecification;
import com.ncr.travel.appmgr.model.shared.Rule;
import com.ncr.travel.appmgr.model.shared.ScreenConfiguration;
import com.ncr.travel.appmgr.model.shared.TableDefinition;
import com.ncr.travel.appmgr.style.client.FunctionToggleButton;

public class RulePresenterImpl extends BasePresenter<RuleView> implements RulePresenter {

	private final AppManagerWebService webService;
	private ScreenConfiguration screenConfiguration;
	private PostScreenConfigurationCommand command;
    /**
     * Factory for screen config model objects.
     */
	private ScreenConfigurationFactory screenConfigurationFactory;
    
	@Inject
	public RulePresenterImpl(AppManagerWebService webService, ScreenConfigurationFactory screenConfigurationFactory, EventBus eventBus, RuleView ruleView) {
		super(eventBus, ruleView);
		System.out.println("Constructing RulePresenter");
		this.screenConfigurationFactory = screenConfigurationFactory;
		this.webService = webService;
		view.setPresenter(this);
		bind();
	}

	/**
	 * @see com.ncr.travel.appmgr.client.presenter.RulePresenter#setScreenConfiguration(com.ncr.travel.appmgr.model.shared.ScreenConfiguration)
	 */
	@Override
	public void setScreenConfiguration(final ScreenConfiguration screenConfiguration) {
		this.screenConfiguration = screenConfiguration;
		view.setScreenConfiguration(this.screenConfiguration);
	}

	@Override
	public void bind() {
		// TODO: S.O.P statements to be replaced with logger
		System.out.println("(RulePresenter) Called bind()");
		registerHandler(eventBus.addHandler(ConfirmConfigChangeEvent.getType(), new ConfirmConfigChangeEventHandler() {
			public void onConfirm(ConfirmConfigChangeEvent event) {
				if (!ConfigurationItem.RULE.equals(event.getConfigurationItem())) {
					// Don't process the event if the event is not generated by
					// RuleView
					return;
				}
				doConfirmRuleChanges();
			}
		}));
	}

	@Override
	public void go(HasWidgets container) {
		container.clear();
		container.add(view.asWidget());
		GWT.runAsync(new RunAsyncCallback() {
			public void onFailure(Throwable caught) {
				Window.alert("Code download failed");
			}

			public void onSuccess() {
				view.showView();
			}
		});
	}

	public final PostScreenConfigurationCommand getCommand() {
		return command;
	}

	private void doConfirmRuleChanges() {

		List<Rule> rules = new ArrayList<Rule>();

		for (int m = 0; m < screenConfiguration.getRules().size(); m++) {

			Rule createRule = screenConfigurationFactory.rule().as();
			Rule rule = screenConfiguration.getRules().get(m);
			rule.setDescription(createRule.getDescription());
			rule.setRuleControls(createRule.getRuleControls());
			rule.setRuleName(createRule.getRuleName());
			rule.setScreenName(createRule.getScreenName());
			rule.setTableDefinition(createRule.getTableDefinition());
			List<TableDefinition> tableDefinitions = new ArrayList<TableDefinition>();

			for (int i = 0; i < view.getModels().length; i++) {

				TableDefinition tableDef = screenConfigurationFactory.tableDefinition().as();
				int rowCount = view.getModel(i).getRowCount();
				tableDef.setRowCount(rowCount);
				int colCount = view.getModel(i).getColumnCount();
				tableDef.setColumnCount(colCount - 1);

				String[] colNames = new String[colCount - 1];
				for (int col = 1; col < colCount; col++) {
					colNames[col - 1] = view.getModel(i).getColumnDescriptor(col).getHeading();
				}
				String rowName = view.getModel(i).getColumnDescriptor(0).getHeading();

				List<RowSpecification> rowSpecifications = new ArrayList<RowSpecification>();
				RowSpecification rowSpecification = null;

				for (int row = 0; row < tableDef.getRowCount(); row++) {
					rowSpecification = screenConfigurationFactory.rowSpecification().as();
					List<ColumnSpecification> colSpecifications = null;
					colSpecifications = new ArrayList<ColumnSpecification>();
					for (int col = 0; col < colCount; col++) {
						System.out.println("row[" + row + "], col[" + col + "]");
						if (col == 0) {
							if (rowName.trim().equals(""))
								rowSpecification.setRowName(null);
							else
								rowSpecification.setRowName(rowName);

							if (view.getModel(i).getCell(row, col) instanceof TextBox) {
								rowSpecification.setRowValue(((TextBox) view.getModel(i).getCell(row, col)).getText());
								rowSpecification.setRowWidget("TextBox");
							} else if (view.getModel(i).getCell(row, col) instanceof CheckBox) {
								rowSpecification.setRowValue(((CheckBox) view.getModel(i).getCell(row, col)).isChecked() + "");
								rowSpecification.setRowWidget("CheckBox");
							} else if (view.getModel(i).getCell(row, col) instanceof Label) {
								rowSpecification.setRowValue(((Label) view.getModel(i).getCell(row, col)).getText());
								rowSpecification.setRowWidget("Label");
							}
						} else {

							ColumnSpecification colSpecification = screenConfigurationFactory.columnSpecification().as();
							colSpecification.setColumnName(colNames[col - 1]);

							if (view.getModel(i).getCell(row, col) instanceof TextBox) {
								colSpecification.setColumnValue(((TextBox) view.getModel(i).getCell(row, col)).getText());
								colSpecification.setColumnWidget("TextBox");
							} else if (view.getModel(i).getCell(row, col) instanceof Label) {
								colSpecification.setColumnValue(((Label) view.getModel(i).getCell(row, col)).getText());
								colSpecification.setColumnWidget("Label");
							} else if (view.getModel(i).getCell(row, col) instanceof HorizontalPanel) {
								HorizontalPanel hp = (HorizontalPanel) view.getModel(i).getCell(row, col);
								FunctionToggleButton button = (FunctionToggleButton) hp.getWidget(0);
								if (button.getStyleName().equals("onButton")) {
									colSpecification.setColumnValue("true");
								} else {
									colSpecification.setColumnValue("false");
								}
								colSpecification.setColumnWidget("ON-OFF");
							}
							if (view.getModel(i).getCell(row, col) instanceof CheckBox) {
								colSpecification.setColumnValue((((CheckBox) view.getModel(i).getCell(row, col)).isChecked()) + "");
								colSpecification.setColumnWidget("CheckBox");
							}

							colSpecifications.add(colSpecification);
						}
					}
					rowSpecification.setColSpecification(colSpecifications);
					rowSpecifications.add(rowSpecification);

				}
				tableDef.setRowSpecification(rowSpecifications);
				tableDefinitions.add(tableDef);
			}
			rule.setTableDefinition(tableDefinitions);
			rules.add(rule);
		}

		final ScreenConfiguration screenConfig = screenConfigurationFactory.screenConfiguration().as();
		screenConfig.setRules(rules);
		command = new PostScreenConfigurationCommand(screenConfig, webService, new JSONCallback<ScreenConfiguration>(screenConfigurationFactory, ScreenConfiguration.class, Constants.MOCK_SERVER_MODE) {
			@Override
			public void onSuccess(ScreenConfiguration screenConfig) {
				eventBus.fireEvent(new ConfigChangeEvent(screenConfig));
			}
			@Override
			public void onFailure(Throwable throwable, int statusCode) {
				// TODO Auto-generated method stub
				
			}
		});
		command.execute();
	}

	@Override
	public Widget createCellWidget(Object cellValue, String type, boolean isHeader) {
		Widget widget = null;

		if (cellValue instanceof Widget) {
			widget = (Widget) cellValue;
		} else {
            /*on/off button will have label header displayed*/
			if (type != null && (type.equals("TextBox")|| (type.equals("ON-OFF") && isHeader))) {
				TextBox tt = new TextBox();
				tt.setSize("200px", "25px");
                tt.setStyleName("confTextBox");
				tt.setText(cellValue.toString());
                if(isHeader) {
                    tt.setReadOnly(true);
                    tt.setStyleName("confTextBoxHeader");
                }
				widget = tt;

				tt.addValueChangeHandler(new ValueChangeHandler<String>() {

					@Override
					public void onValueChange(ValueChangeEvent<String> event) {

						view.getConfigEditor().enablePreviewControl();

					}
				});

			} else if (type != null && type.equals("Label") ) {
				Label tt = new Label();
				String value = (String) cellValue;
				if (value == null)
					tt.setText("  ");
				else
					tt.setText(value);
				tt.setStyleName("confLabelRegular");
				if(isHeader) {
				    tt.setStyleName("confLabelText11ptBold");
				}
				widget = tt;
			} else if (type != null && type.equals("ON-OFF")) {

			    if(!isHeader) {
    				boolean val = false;
    				//				final Button on = new Button();
    				final FunctionToggleButton on = new FunctionToggleButton();
    				
    				on.getButton().addClickHandler(new ClickHandler(){

                        @Override
                        public void onClick(ClickEvent event) {
                            view.getConfigEditor().enablePreviewControl();
                        }
    				    
    				});
    				
    				widget = (Widget) on;
			    }
			} else if (type != null && type.equals("CheckBox")) {
				final SimpleCheckBox ch = new SimpleCheckBox();
				ch.addClickHandler(new ClickHandler() {
					public void onClick(ClickEvent event) {

						view.getConfigEditor().enablePreviewControl();

						/*com.google.gwt.user.client.ui.HTMLTable.Cell cell = flexTable.getCellForEvent(event);
						// celDelete.add(cell)
						int deleteIndex = cell.getRowIndex();

						if (ch.isChecked() == true) {
							deleteList.add(deleteIndex);
						} else {
							int index = deleteList.indexOf(deleteIndex);
							deleteList.remove(index);
						}*/
					}

				});
				if (cellValue != null) {
					if (cellValue.toString().equals("\"true\"")) {

						ch.setValue(true);
						//						deleteList.add(flexTable.getRowCount());
					} else {

						ch.setValue(false);
					}
				}
                ch.addStyleName("confCheckBox");
				if(isHeader) {
				    ch.setStyleName("confCheckBoxHeader");
				    ch.setEnabled(false);
				}
				widget = ch;
			}
		}
		return widget;
	}
}
